import React from 'react';
import PropTypes from 'prop-types';
import {Tree, Spin} from 'antd';
const TreeNode = Tree.TreeNode;
import {union} from 'lodash';
const calcLink = (id, pages, paths) => {
    if(!id)
        return;
    for(let i = 0; i < pages.length; i++)
        /*eslint-disable  eqeqeq*/
        if(pages[i].id == id || (pages[i].items && calcLink(id, pages[i].items, paths))) {
            paths.push(`${pages[i].id}`);
            return true;
        }
};

class CategoryTree extends React.PureComponent {
    static getDerivedStateFromProps(props, state) {
        if(props.locatedKey === state.locatedKey)
            return null;
        if(!props.locatedKey)
            return {locatedKey: null};
        const link = [];
        calcLink(props.locatedKey, props.pages, link);
        if(link.length === 0)
            return null;
        return {
            locatedKey: props.locatedKey,
            expandedKeys: union(state.expandedKeys, link.slice(1))
        };
    }

    constructor(props) {
        super(props);
        const link = [];
        this.state = {
            locatedKey: props.locatedKey ? props.locatedKey.toString() : '',
            expandedKeys: (props.locatedKey && calcLink(props.locatedKey, props.pages, link)) ? link.slice(1) : [],
        };
        this.onExpand = this.onExpand.bind(this);
        this.onSelect = this.onSelect.bind(this);
        this.onLoadData = this.onLoadData.bind(this);
        this.renderTreeNodes = this.renderTreeNodes.bind(this);
    }
    

    renderTreeNodes(data = []) {
        const _ = this;
        return data.map(item =>
            <TreeNode key={item.id}
                title={item.code ? `${item.name}(${item.code})` : item.name}
                dataRef={item}
                isLeaf={item.isLeaf}
                selectable={_.props.selectable(item)}>
                {!item.isLeaf && this.renderTreeNodes(item.items)}
            </TreeNode>
        );
    }

    onExpand(expandedKeys) {
        this.setState({expandedKeys});
    }

    onSelect(selectedKeys, e) {
        const id = e.selected ? selectedKeys[0] : this.props.locatedKey.toString();
        if(id !== this.props.locatedKey.toString())
            this.props.onSelect(id, e.node.props.dataRef);
    }

    onLoadData(node) {
        const data = node.props.dataRef;
        return data.items && data.items.length
            ? Promise.resolve()
            : this.props.onLoadData(data);
    }
    render() {
        return (
            <Spin spinning={this.props.loading}>
                <Tree loadData={this.onLoadData} onExpand={this.onExpand} onSelect={this.onSelect}
                    expandedKeys={this.state.expandedKeys}
                    selectedKeys={this.props.locatedKey ? [this.props.locatedKey.toString()] : null}
                    autoExpandParent={false}>
                    {this.renderTreeNodes(this.props.pages)}
                </Tree>
            </Spin>
        );
    }
}

/**
 * 树形结构展示CategoryTree
 */
CategoryTree.propTypes = {
    /**
     * 页面数据
     * pages: [{
     *      id: required,
     *      items: pages,    子节点
     *      name: required,     名称
     *      code: required,     编号
     *      isLeaf: required, 是否叶子节点
     * }]
     * }
     */
    pages: PropTypes.array.isRequired,
    /**
     * 展开节点需要异步获取数据时触发
     * @param node  节点数据
     */
    onLoadData: PropTypes.func.isRequired,
    /**
     * 选中节点时触发
     * @param id  当前选中节点的id
     */
    onSelect: PropTypes.func.isRequired,
    loading: PropTypes.bool,
    locatedKey: PropTypes.oneOfType([
        PropTypes.string,
        PropTypes.number
    ]),
    /**
     * 设置节点是否可选择
     * @default true 默认可选中
     */
    selectable: PropTypes.func,
};

CategoryTree.defaultProps = {
    pages: [],
    locatedKey: '',
    onLoadData: () => Promise.resolve(),
    onSelect: () => Promise.resolve(),
    selectable: () => true
};

export default CategoryTree;
